package ferp.android.tasks.local;

import android.os.AsyncTask;
import ferp.android.activities.Ferp;
import ferp.android.services.IResolverService2;
import ferp.android.services.ServiceException;
import ferp.android.services.ServiceProxy;
import ferp.core.card.Card;
import ferp.core.game.Game;
import ferp.core.game.Trick;
import ferp.core.mode.Moving;
import ferp.core.player.Hand;
import ferp.core.state.State;

/**
 * User: olegs
 * Date: 2/3/13 11:12 AM
 */
public class TaskGameResume extends AsyncTask<Void, Void, ServiceException>
{
  public TaskGameResume(Ferp ferp, Game game, boolean rostov, IResolverService2 service)
  {
    this.ferp    = ferp;
    this.game    = game;
    this.rostov  = rostov;
    this.service = service;
  }

  @Override
  protected void onPreExecute()
  {
    ferp.onGameResumeStarted(game);
  }

  @Override
  protected ServiceException doInBackground(Void... voids)
  {
    try
    {
      Moving mode = (Moving)game.mode();
      int dropReal = game.getDropHash(0) | game.getDropHash(1);
      int[] hands = new int[Game.PLAYERS];

      for (int i = 0; i < Game.PLAYERS; ++i)
      {
        // add current hand of the player
        hands[i] = Hand.add(hands[i], game.getHand(i).current);

        Card card = Trick.card(game.trick.current, i);

        if (card != null)
        {
          // add played card to the right hand
          byte owner = Trick.owner(game.trick.current, i);

          hands[owner] = Hand.add(hands[owner], card.hash);
        }
      }

      // initialize
      ServiceProxy.initialize(service, mode.evaluator(), game.player.declarer, game.player.starting, game.trump().ordinal(),
                              hands[0], hands[1], hands[2],
                              game.getTalonCompressed(0), game.getTalonCompressed(1),
                              dropReal, dropReal, game.rounds, game.type == Game.Type.UNKNOWN || game.type == Game.Type.OPEN, rostov, game.service);

      // solve
      ServiceProxy.solve(service);

      // advance
      int trick = 0;
      for (int i = 0; i < Game.PLAYERS; ++i)
      {
        Card card = Trick.card(game.trick.current, i);

        if (card != null)
        {
          byte owner = Trick.owner(game.trick.current, i);
          trick = Trick.add(trick, owner, card.compressed);

          ServiceProxy.advance(service, i, trick);
        }
      }

      return null;
    }
    catch (ServiceException e)
    {
      return e;
    }
  }

  @Override
  protected void onPostExecute(ServiceException e)
  {
    // note: the compatibility with old versions (prior to 38) requires checking the trick size
    //       as the save could happen in any state
    // next state in GIO if trick size < 3, otherwise the last saved state
    if (e == null)
    {
      if (game.state() != State.gio && Trick.size(game.trick.current) < 3)
      {
        game.options.clear();
        game.set(State.gio);
      }

      ferp.onGameResumeFinished(game);
    }
    else
      ferp.exit(e);
  }

  private Ferp ferp;
  private Game game;
  private boolean rostov;
  private IResolverService2 service;
}
